package com.ruoyi.hr.service.impl;

import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.hr.domain.JUser;
import com.ruoyi.hr.domain.salaryCalculation.AttendDatas;
import com.ruoyi.hr.domain.salaryCalculation.SkypayGroups;
import com.ruoyi.hr.mapper.EmpSalaryCalculationMapper;
import com.ruoyi.hr.mapper.SkyMsgAlarmMapper;
import com.ruoyi.hr.service.EmpSalaryCalculationService;
import com.ruoyi.hr.util.BaseResult;
import com.ruoyi.hr.util.ExcelUtils;
import com.ruoyi.hr.util.ResultEnum;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.mapper.SysUserMapper;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileOutputStream;
import java.util.*;

@Service
public class EmpSalaryCalculationServiceImpl implements EmpSalaryCalculationService {
    @Autowired
    private EmpSalaryCalculationMapper empSalaryCalculationMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SkyMsgAlarmMapper skyMsgAlarmMapper;

    /**
     * 获取所有薪资套类型
     *
     * @return
     */
    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<SkypayGroups> findSkypayGroups(String urid) {
        return empSalaryCalculationMapper.findSkypayGroups(urid);
    }

    /**
     * 获取薪资人员信息
     *
     * @param sql
     * @return
     */
    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<Map> findEmpSalaryInfoList(String sql) {
        Map<String, Object> map = new HashMap<>();
        map.put("sql", sql);
        return empSalaryCalculationMapper.findEmpSalaryInfoList(map);
    }

    /**
     * 获取JSID
     * @param JSID
     * @return
     */
    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String getJSID(String JSID) {
        return empSalaryCalculationMapper.getJSID(JSID);
    }

    /**
     * 获取薪资套项目
     * @param pgid
     * @return
     */
    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<String> findObjType(String pgid) {
        return empSalaryCalculationMapper.findObjType(pgid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<String> findObjTypeAll(String jsid) {
        return empSalaryCalculationMapper.findObjTypeAll(jsid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public BaseResult findNewTerm(String pgid) {
        try {
            Map<String, Object> map = empSalaryCalculationMapper.findNewTerm(pgid);
            if (null == map) {
                //若刚封账就进行初始化肯定是没有数据的,去历史表中查并加一月
                map = empSalaryCalculationMapper.findNewTermAll(pgid);
            }
            return BaseResult.build(ResultEnum.SUCCESS, map);
        } catch (Exception e) {
            return BaseResult.build(ResultEnum.SERVER_ERROR);
        }
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String Initialization(String sql) {
        return empSalaryCalculationMapper.Initialization(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<String> findKQ() {
        return empSalaryCalculationMapper.findKQ();
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<String> findYJYK(String pgid) {
        return empSalaryCalculationMapper.findYJYK(pgid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<JUser> findWorking(String jsid) {
        return empSalaryCalculationMapper.findWorking(jsid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<String> findObjsId(List<String> objProList) {
        return empSalaryCalculationMapper.findObjsId(objProList);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String findWorkID(String badge) {
        return empSalaryCalculationMapper.findWorkID(badge);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String findPeidByBadge(String badge) {
        return empSalaryCalculationMapper.findPeidByBadge(badge);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public int deleteAttend(String term, String jsid) {
        return empSalaryCalculationMapper.deleteAttend(term, jsid);
    }


    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public int deleteADJUST(String term, String jsid) {
        return empSalaryCalculationMapper.deleteADJUST(term, jsid);
    }


    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String findStartDate(String jsid) {
        return empSalaryCalculationMapper.findStartDate(jsid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String findEndDate(String jsid) {
        return empSalaryCalculationMapper.findEndDate(jsid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public int insertObjsWorking(String StartDate, String endDate, List<AttendDatas> attendDatas) {
        return empSalaryCalculationMapper.insertObjsWorking(StartDate, endDate, attendDatas);
    }


    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void skyPayGroupSubmitBefore(String pgid) {
        empSalaryCalculationMapper.skyPayGroupSubmitBefore(pgid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void skyPayGroupSubmitpgid(String sql) {
        empSalaryCalculationMapper.skyPayGroupSubmitpgid(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void skyPayGroupSubmit(String sql) {
        empSalaryCalculationMapper.skyPayGroupSubmit(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void skyPayGroupFreeze(String sql) {
        empSalaryCalculationMapper.skyPayGroupFreeze(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void skyPayGroupCancel(String sql) {
        empSalaryCalculationMapper.skyPayGroupCancel(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void skyPayGroupClose(String sql) {
        empSalaryCalculationMapper.skyPayGroupClose(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public List<Map<String, Object>> findEmpByPgid(String pgid) {
        return empSalaryCalculationMapper.findEmpByPgid(pgid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String findObjIdByTitle(String title) {
        return empSalaryCalculationMapper.findObjIdByTitle(title);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult downloadTemplate(String type, String pgid) {
        try {
            HSSFWorkbook wkb = new HSSFWorkbook();
            //获取考勤列名
            List<String> list = new ArrayList<String>();
            String sheetname = "";
            if ("kq".equals(type)) {
                list = empSalaryCalculationMapper.findKQ();
                sheetname = "考勤模板";
            } else {
                list = empSalaryCalculationMapper.findYJYK(pgid);
                sheetname = "应扣应减模板";
            }
            //设置Sheet名称
            HSSFSheet sheet = wkb.createSheet(sheetname);
            //新增一行(用于列名)
            HSSFRow row1 = sheet.createRow(0);
            if ("kq".equals(type)) {
                //设置固定列名
                row1.createCell(0).setCellValue("工号");
                row1.createCell(1).setCellValue("姓名");
                row1.createCell(2).setCellValue("公司");
                row1.createCell(3).setCellValue("部门");
                row1.createCell(4).setCellValue("岗位");
                row1.createCell(5).setCellValue("薪资区域");
                for (int i = 0; i < list.size(); i++) {
                    sheet.setColumnWidth(i, 16 * 256);
                    row1.createCell(i + 6).setCellValue(list.get(i));
                }
                List<Map<String, Object>> empList = empSalaryCalculationMapper.findEmpByPgid(pgid);
                //写入Excel
                HSSFRow row;
                for (int i = 1; i <= empList.size(); i++) {
                    //循环写入行
                    row = sheet.createRow(i);
                    row.createCell(0).setCellValue(empList.get(i - 1).get("badge").toString());
                    row.createCell(1).setCellValue(empList.get(i - 1).get("name").toString());
                    row.createCell(2).setCellValue(empList.get(i - 1).get("compName").toString());
                    row.createCell(3).setCellValue(empList.get(i - 1).get("depName").toString());
                    row.createCell(4).setCellValue(empList.get(i - 1).get("jobName").toString());
                    row.createCell(5).setCellValue(empList.get(i - 1).get("pzidName").toString());
                }
            } else {
                //设置固定列名
                row1.createCell(0).setCellValue("工号");
                row1.createCell(1).setCellValue("姓名");
                row1.createCell(2).setCellValue("公司");
                row1.createCell(3).setCellValue("部门");
                row1.createCell(4).setCellValue("岗位");
                row1.createCell(5).setCellValue("入职日期");
                row1.createCell(6).setCellValue("起薪日期");
                for (int i = 0; i < list.size(); i++) {
                    sheet.setColumnWidth(i, 16 * 256);
                    row1.createCell(i + 7).setCellValue(list.get(i));
                }
                List<Map<String, Object>> empList = empSalaryCalculationMapper.findEmpByPgid(pgid);
                //写入Excel
                HSSFRow row;
                for (int i = 1; i <= empList.size(); i++) {
                    //循环写入行
                    row = sheet.createRow(i);
                    row.createCell(0).setCellValue(empList.get(i - 1).get("badge").toString());
                    row.createCell(1).setCellValue(empList.get(i - 1).get("name").toString());
                    row.createCell(2).setCellValue(empList.get(i - 1).get("compName").toString());
                    row.createCell(3).setCellValue(empList.get(i - 1).get("depName").toString());
                    row.createCell(4).setCellValue(empList.get(i - 1).get("jobName").toString());
                    row.createCell(5).setCellValue(empList.get(i - 1).get("EmpStartDate").toString());
                    row.createCell(6).setCellValue(empList.get(i - 1).get("StartDate").toString());
                }
            }
            String filePath = Global.getDownloadPath() + sheetname + ".xls";
            FileOutputStream fileOut = new FileOutputStream(filePath);
            wkb.write(fileOut);
            fileOut.close();
            return AjaxResult.success(0);
        } catch (Exception e) {
            return AjaxResult.error("失败");
        }
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult exportSalaryData(String pgid, List<Map> maps) {
        try {
            HSSFWorkbook wkb = new HSSFWorkbook();

            //获取数据列名
            List<String> ProList = empSalaryCalculationMapper.findObjTypeAll(pgid);
            for (int i = 0; i < ProList.size(); i++) {
                ProList.set(i, ProList.get(i).replace("（", "("));
                ProList.set(i, ProList.get(i).replace("）", ")"));
            }
            String sheetname = "薪资数据导出";
            //设置Sheet名称
            HSSFSheet sheet = wkb.createSheet(sheetname);
            //新增一行(用于列名)
            HSSFRow row1 = sheet.createRow(0);
            //设置固定列名
            row1.createCell(0).setCellValue("时间");
            row1.createCell(1).setCellValue("员工编号");
            row1.createCell(2).setCellValue("姓名");
            row1.createCell(3).setCellValue("公司名称");
            row1.createCell(4).setCellValue("部门名称");
            row1.createCell(5).setCellValue("岗位名称");
            row1.createCell(6).setCellValue("在岗状态");
            row1.createCell(7).setCellValue("入职日期");
            row1.createCell(8).setCellValue("离职日期");
            for (int i = 0; i < ProList.size(); i++) {
                sheet.setColumnWidth(i, 16 * 256);
                row1.createCell(i + 9).setCellValue(ProList.get(i));
            }
            //将数据放到Excel中
            HSSFRow row;
            for (int i = 1; i <= maps.size(); i++) {
                //循环写入行
                row = sheet.createRow(i);
                row.createCell(0).setCellValue(maps.get(i - 1).get("时间").toString());
                row.createCell(1).setCellValue(maps.get(i - 1).get("badge").toString());
                row.createCell(2).setCellValue(maps.get(i - 1).get("name").toString());
                row.createCell(3).setCellValue(maps.get(i - 1).get("公司名称").toString());
                row.createCell(4).setCellValue(maps.get(i - 1).get("部门名称").toString());
                row.createCell(5).setCellValue(maps.get(i - 1).get("岗位名称").toString());
                row.createCell(6).setCellValue(maps.get(i - 1).get("在岗状态").toString());
                row.createCell(7).setCellValue(maps.get(i - 1).get("EmpStartDate").toString());
                row.createCell(8).setCellValue(maps.get(i - 1).get("EmpEndDate").toString());
                for (int j = 0; j < ProList.size(); j++) {
                    row.createCell(j + 9).setCellValue(maps.get(i - 1).get(ProList.get(j)).toString());
                }
            }
            String filePath = Global.getDownloadPath() + sheetname + ".xls";
            FileOutputStream fileOut = new FileOutputStream(filePath);
            wkb.write(fileOut);
            fileOut.close();
            return AjaxResult.success(0);
        } catch (Exception e) {
            return AjaxResult.error("失败");
        }
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult importData(MultipartFile file, boolean updateSupport, String pgid, String type) {

        int fixedFieldsNum = 0;
        if ("kq".equals(type)) {
            fixedFieldsNum = 6;
        } else {
            fixedFieldsNum = 7;
        }

        //获取Excel数据  0节点为所有项目名 为String数组
        List<String[]> excelData = ExcelUtils.getExcelData(file);

        //取出第一行所有title对应的id,存在map里
        List<String> ObjProList = new ArrayList<String>();
        for (String s : excelData.get(0)) {
            ObjProList.add(s);
        }

        //查到项目ID存在Map中
        List<String> ObjProIDList = empSalaryCalculationMapper.findObjsId(ObjProList);
        //组合ID和项目名
        Map<String, String> map = new HashMap<String, String>();
        for (int i = 0; i < ObjProIDList.size(); i++) {
            map.put(ObjProList.get(i + fixedFieldsNum), ObjProIDList.get(i));
        }

        SysUser user = ShiroUtils.getSysUser();
        //导入Excel人员id
        Map<String, Object> maps = sysUserMapper.selectSkySecUser(user.getLoginName());
        String initialized = maps.get("id").toString();
        //根据pgid查出时间
        Map<String, Object> map1 = empSalaryCalculationMapper.findNewTerm(pgid);
        String term = map1.get("term").toString();
        //根据pgid取出jsid
        String jsid = getJSID(pgid);
        //定义数据集合
        List<AttendDatas> attendDatasList = new ArrayList<AttendDatas>();

        //先删除
        if ("kq".equals(type)) {
            empSalaryCalculationMapper.deleteAttend(term, jsid);
        } else {
            empSalaryCalculationMapper.deleteADJUST(term, jsid);
        }

        AttendDatas attendDatas = new AttendDatas();

        //循环字段,从动态开始
        for (int i = 1; i < excelData.size(); i++) {
            for (int j = fixedFieldsNum; j < excelData.get(0).length; j++) {
                //判断是否越界,如果越界则插入后面的,amount为null
                if (excelData.get(i).length == j) {
                    //如果等于了,再往后就越界了,插入所有后面的,值为null
                    for (int x = j; x < excelData.get(0).length; x++) {
                        attendDatas.setTerm(term);
                        attendDatas.setPeid(empSalaryCalculationMapper.findPeidByBadge(excelData.get(i)[0]));
                        attendDatas.setObjID(map.get(excelData.get(0)[x]));
                        attendDatas.setAmount(null);
                        attendDatas.setInitialized(initialized);
                        attendDatas.setJsid(jsid);
                        if (fixedFieldsNum == 6) {
                            empSalaryCalculationMapper.insertAttend(attendDatas);
                        } else {
                            empSalaryCalculationMapper.insertADJUST(attendDatas);
                        }
                    }
                    //插入完成后代表这个人就结束了,跳出内部循环
                    break;
                }
                String amount = excelData.get(i)[j];
                if ("".equals(amount) || "0".equals(amount)) {
                    amount = null;
                    System.out.println(excelData.get(i)[1] + "的" + excelData.get(0)[j] + "为" + amount + " id为" + map.get(excelData.get(0)[j]));
                }
                //生成实体类
                attendDatas.setTerm(term);
                attendDatas.setPeid(empSalaryCalculationMapper.findPeidByBadge(excelData.get(i)[0]));
                attendDatas.setObjID(map.get(excelData.get(0)[j]));
                attendDatas.setAmount(amount);
                attendDatas.setInitialized(initialized);
                attendDatas.setJsid(jsid);
                if (fixedFieldsNum == 6) {
                    empSalaryCalculationMapper.insertAttend(attendDatas);
                } else {
                    empSalaryCalculationMapper.insertADJUST(attendDatas);
                }
            }
        }
        return AjaxResult.success(0);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String executeProcedure(String sql) {
        return empSalaryCalculationMapper.executeProcedure(sql);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public Map<String, Object> refreshButton(String pgid) {
        return empSalaryCalculationMapper.refreshButton(pgid);
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public String salaryProcess(Map map) {
        String sql = "";
        SysUser user = ShiroUtils.getSysUser();
        Map<String, Object> maps = sysUserMapper.selectSkySecUser(user.getLoginName());
        String urid = maps.get("id").toString();
        //初始化
        try {
            String type = map.get("type").toString();
            //前
            if (type.equals("submitBefore")) {
                //调用计算前的两个存储过程
                sql = "declare @RetVal varchar(50) exec skyPayGroupSubmit " + map.get("pgid") + "," + urid + ",@RetVal output select @RetVal";
                String result = empSalaryCalculationMapper.executeProcedure(sql);
                if (!result.equals("0")) {
                    return skyMsgAlarmMapper.getMsgById(empSalaryCalculationMapper.executeProcedure(sql));
                }
                sql = "declare @RetVal varchar(50) exec skyPayGroupSubmitBefore " + map.get("pgid") + "," + urid + ",@RetVal output select @RetVal";
                result = empSalaryCalculationMapper.executeProcedure(sql);
                if (!result.equals("0")) {
                    return skyMsgAlarmMapper.getMsgById(empSalaryCalculationMapper.executeProcedure(sql));
                }
                sql = getProcedure(map);
                empSalaryCalculationMapper.executeProcedure(sql);
            } else if (type.equals("closed")) {
                //调用封账前的一个存储过程
                sql = "declare @RetVal varchar(50) exec skyPayGroupCloseBefore " + map.get("pgid") + "," + urid + ",@RetVal output select @RetVal";
                String result = empSalaryCalculationMapper.executeProcedure(sql);
                if (result.equals("930088")) {
                    return skyMsgAlarmMapper.getMsgById(empSalaryCalculationMapper.executeProcedure(sql));
                }
                //没问题调用封账的中间的存储过程
                sql = getProcedure(map);
                result = empSalaryCalculationMapper.executeProcedure(sql);
                if (null != result) {
                    return skyMsgAlarmMapper.getMsgById(result);
                }
            } else if (type.equals("init")) {
                sql = getProcedure(map);
                String result = empSalaryCalculationMapper.Initialization(sql);
                if (null != result) {
                    return skyMsgAlarmMapper.getMsgById(result);
                }
            } else {
                //中
                sql = getProcedure(map);
                empSalaryCalculationMapper.executeProcedure(sql);
            }
            //后
            if (type.equals("closed")) {
                sql = "declare @RetVal varchar(50) exec skyPayGroupCloseAfter " + map.get("pgid") + "," + urid + ",@RetVal output select @RetVal";
                empSalaryCalculationMapper.executeProcedure(sql);
            }
            if (type.equals("init")) {
                return "初始化完成";
            } else if (type.equals("submitBefore")) {
                return "计算完成";
            } else if (type.equals("submit")) {
                return "计算完成";
            } else if (type.equals("freeze")) {
                return "冻结成功";
            } else if (type.equals("cancel")) {
                return "取消冻结成功";
            } else if (type.equals("closed")) {
                return "封存成功";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "错误";
    }

    public String getProcedure(Map map) {
        //操作类型
        String type = map.get("type").toString();
        //薪资类型
        String pgid = map.get("pgid").toString();
        //权限URID

        SysUser user = ShiroUtils.getSysUser();
        Map<String, Object> maps = sysUserMapper.selectSkySecUser(user.getLoginName());
        String urid = maps.get("id").toString();

        //叠加sql
        String sql = "";
        if (type.equals("init")) {
            //初始化
            sql = " declare @RetVal varchar(50) exec skyPayGroupInit" + pgid + " " + pgid + ",'" + map.get("term") + "',";
            //初始化是否保留当前数据
            if (map.get("reserveData").toString().equals("true")) {
                sql += "1,";
            } else {
                sql += "null,";
            }
            sql += urid + ",@RetVal output select @RetVal";
        } else if (type.equals("submitBefore")) {
            //计算
            sql = "skyPayGroupSubmit" + pgid + " " + pgid + "," + urid + ",0";
        } else if (type.equals("freeze")) {
            //冻结
            sql = "skyPayGroupFreeze " + pgid + "," + urid + ",0";
        } else if (type.equals("cancel")) {
            //取消冻结
            sql = "skyPayGroupCancel " + pgid + "," + urid + ",0";
        } else if (type.equals("closed")) {
            //封账
            sql = "skyPayGroupClose " + pgid + "," + urid + ",0";
        }
        return sql;
    }
}
